// Playground - noun: a place where people can play
/**
* swift函数demo
**/
import UIKit

//带形参返回值类型为String的函数
func sayHello(personName:String) -> String{
    return "Hello " + personName;
}

sayHello("edvard");

//计算字母元音啥的
func count(string:String)->(vowel:Int,consonant:Int,others:Int){
    var vowel = 0,consonant = 0,others = 0;
    for character in string{
        switch String(character).lowercaseString{
        case "a","e","i","o","u":
        vowel++;
        case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
            "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
            consonant++;
        default:
            others++;
        }
    }
    return (vowel,consonant,others);
}

var tuple = count("abcdefg");

//外部形参名称，让代码看上去更像自然语言

func stringJoin(string s1:String , toString s2:String , joiner string:String)->String{
    return s1 + string + s2;
}

stringJoin(string: "1", toString: "2", joiner: "+")

//可变参数的函数

func daymicVariable(num:Int...)->Int{
    return num.count;
}

daymicVariable(1,2,3,4);

//局部可变的形参
func partChange(var variable:String)->String{
    variable = "b";
    return variable;
}

partChange("a");

//类比c语言，传地址进入函数

func changeOriginValue(inout a:String){
    a = "change";
}

var b = "Will Change";
changeOriginValue(&b);
b;


func addTwoInts(a:Int,b:Int)->Int{
    return a+b;
}

//使用函数类型
var mathFunction:(Int,Int) -> Int = addTwoInts;

//函数类型作为形参
func printMathResult(mathFunction:(Int,Int)->Int,a:Int,b:Int){
    println("Result: \(mathFunction(a,b))");
}

printMathResult(mathFunction, 5, 5);

func stepBackward(var number:Int)->Int{
    return --number;
}

func stepForward(var number:Int)->Int{
    return ++number;
}

func chooseStepFunction(backwards:Bool)->(Int)->Int{
    return backwards ? stepBackward : stepForard;
}

var currentValue:Int = 10;
var moveNextToZero = chooseStepFunction(currentValue > 0);

while currentValue != 0{
    println("currentValue \(currentValue)");
    moveNextToZero(currentValue);
}
println("zero");
currentValue;

//嵌套函数返回函数类型
func chooseStepFunctioNesting(backward:Bool)->(Int)->Int{
    func stepBackWard(var number:Int)->Int{
        return --number;
    }
    func stepForward(var number:Int)->Int{
        return ++number;
    }
    
    return backward ? stepBackWard : stepForward;
}
